package rtype

import (
	"reflect"
	"unsafe"
)

const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const

// EmptyInterface 接口类型底层结构
type EmptyInterface struct {
	Typ  *Rtype
	Word unsafe.Pointer
}

// GetValue 类型标记
func (eif *EmptyInterface) GetValue() *reflect.Value {
	if eif == nil {
		return nil
	}
	f := Flag(eif.Typ.Kind())
	if eif.Typ.KindC&KindDirectIface == 0 {
		f |= FlagIndir
	}
	ptr := &Value{}
	ptr.Typ = eif.Typ
	ptr.Ptr = eif.Word
	ptr.Flag = f
	return (*reflect.Value)(unsafe.Pointer(ptr))
}

// Pointer 得到指针
//@! 根据其 Value.go 包定义编写
func (eif EmptyInterface) Pointer() unsafe.Pointer {
	typ := eif.Typ
	ptr := eif.Word
	if typ == nil || ptr == nil {
		return nil
	}
	// 判定是否为指针
	if typ.Size != PtrSize || typ.Ptrdata == 0 {
		return nil
	}
	// 是否为指针
	flag := typ.Flag()
	if flag&FlagIndir != 0 {
		ptr = *(*unsafe.Pointer)(ptr)
	}
	return ptr
}

// MapType represents a map type.
type MapType struct {
	Rtype
	Key    *Rtype // map key type
	Elem   *Rtype // map element (value) type
	Bucket *Rtype // internal bucket structure
	// function for hashing keys (ptr to key, seed) -> hash
	Hasher     func(unsafe.Pointer, uintptr) uintptr
	Keysize    uint8  // size of key slot
	Valuesize  uint8  // size of value slot
	Bucketsize uint16 // size of bucket
	Flags      uint32
}

// PtrType represents a pointer type.
type PtrType struct {
	Rtype
	Elem *Rtype // pointer element (pointed at) type
}

// Name 名称
type Name struct {
	Bytes *byte
}

// StructField Struct field
type StructField struct {
	Name        Name    // name is always non-empty
	Typ         *Rtype  // type of field
	OffsetEmbed uintptr // byte offset of field<<1 | isEmbedded
}

// Offset 底层函数
func (f *StructField) Offset() uintptr {
	return f.OffsetEmbed >> 1
}

// Embedded 底层函数
func (f *StructField) Embedded() bool {
	return f.OffsetEmbed&1 != 0
}

// StructType represents a struct type.
type StructType struct {
	Rtype
	PkgPath Name
	Fields  []StructField // sorted by offset
}
